package com.xianggu.threadPool;

import com.xianggu.threadPool.rejectStrategy.RejectHandle;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author chengjy
 * @date 2025/3/14
 */
public class MyThreadPool {

    private int corePoolSize;
    private int maxPoolSize;
    private int timeOut;
    private TimeUnit timeUnit;

    // 定义一个阻塞队列容器存储任务
    private BlockingQueue<Runnable> taskQueue;
    // 存储线程的容器
    private List<Thread> coreThreadList = new ArrayList<>();
    private List<Thread> tempThreadList = new ArrayList<>();
    private RejectHandle rejectHandle;

    public MyThreadPool(int corePoolSize , int maxPoolSize, int timeOut, TimeUnit timeUnit,
                        BlockingQueue<Runnable> taskQueue, RejectHandle rejectHandle) {
        this.taskQueue = taskQueue;
        this.rejectHandle = rejectHandle;
        if (taskQueue == null) {
            taskQueue = new ArrayBlockingQueue<>(maxPoolSize);
        }

        this.corePoolSize = corePoolSize;
        this.maxPoolSize = maxPoolSize;
        this.timeOut = timeOut;
        this.timeUnit = timeUnit;
    }

    public void execute(Runnable runnable) {
        // 有任务进行优先加入到阻塞队列中
        boolean isOffer = taskQueue.offer(runnable);

        // 如果当前线程数小于核心线程数，则开启新的线程执行任务
        if (coreThreadList.size() < corePoolSize) {
            // 创建一个核心线程执行任务
            Thread coreThread = new CoreThread();
            coreThread.start();
            coreThreadList.add(coreThread);
        }
        // 核心线程数以全部创建，但队列已满，创建临时线程
        if (coreThreadList.size() < maxPoolSize && !isOffer) {
            // 创建一个临时线程执行任务
            Thread coreThread = new TempThread();
            coreThread.start();
            tempThreadList.add(coreThread);
            // 再次尝试加入队列
            isOffer = taskQueue.offer(runnable);
        }

//        System.out.println("当前队列任务数：" + taskQueue.size() + "，当前线程数：" + coreThreadList.size() + "，临时线程数：" + tempThreadList.size());
        if (!isOffer) {
            // 执行拒绝策略
            rejectHandle.reject(this , runnable);
        }
    }

    class CoreThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    // 阻塞获取任务
                    Runnable take = taskQueue.take();
                    // 睡眠一秒，模拟任务执行时间
                    Thread.sleep(1000);

                    Thread.currentThread().setName("核心线程" + Thread.currentThread().getId());
                    take.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    class TempThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    // 阻塞获取任务
                    Runnable take = taskQueue.poll(timeOut, timeUnit);
                    // 睡眠一秒，模拟任务执行时间
                    Thread.sleep(1000);

                    if (take == null) {
                        // 如果队列为空，则关闭线程
                        tempThreadList.remove(this);
                        System.out.println(Thread.currentThread().getName() +  " 临时线程关闭！");
                        return;
                    }
                    Thread.currentThread().setName("临时线程" + Thread.currentThread().getId());
                    take.run();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public BlockingQueue<Runnable> getTaskQueue() {
        return taskQueue;
    }
}
